package com.yonyou.isv.demo.openapi.verify;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

/**
 * @author nishch
 * @description: TODO  比较json ，
 * @date 2021/10/13
 */
@Component
public class VerifyJson {

    private final  static  String  STANDARDJSON = "verify/standardjson.txt";  //标准JSON
    private final  static  String  CUSCOMPARE = "verify/cuscompare.txt";  //客户拼装JSON
    private final  static  String  EMPTYSTRING = "verify/empty.txt";


    public JSONObject getRequiredFromCusJson(String... keys) throws IOException {
        String standardJson = readJson(STANDARDJSON);  //标准JSON
        JSONObject jsonObject = JSONObject.parseObject(standardJson);
        Map<String,Set<String>> standMap = getSets(jsonObject,keys); //获取到标准JSON的所有key
        String cusCompare = readJson(CUSCOMPARE);  //客户JSON
        JSONObject cusObject = JSONObject.parseObject(cusCompare);
        standMap.forEach((key,value)->{
            Object data = null;
            if(key.equals("data")){   ///主表只支持取第一条数据进行比较
                data = cusObject.get("data");
                //移除不需要的对象
                if(data instanceof JSONArray){
                    data = ((JSONArray) data).get(0);
                }
            }else{
                if(cusObject.get("data") instanceof JSONArray){
                    data = ((JSONObject)((JSONArray) cusObject.get("data")).get(0)).get(key); //子表只支持取第一条数据进行比较
                    if(data instanceof JSONArray){
                        data = ((JSONArray) data).get(0);
                    }
                }else{
                    if(!cusObject.containsKey("data")){
                        data = cusObject.get(key);
                    }else{
                        data = ((JSONObject)cusObject.get("data")).get(key);
                    }
                }
            }
            Map<String,Object> jsonCus = data instanceof  JSONArray ? (Map<String,Object>)(((JSONArray) data).get(0)):(Map<String,Object>)data;
            //取出value中包含!号的字段，从客户JSON中取值再赋值;应对标准JSON中包含!号的情况
            doExclamationPoint(jsonCus,value);
            //同可以保存成功的JSON对比移除客户JSON中不必传的字段
            removeChTable(keys,jsonCus);
            //同可以保存成功的JSON对比移除客户JSON中不必传的字段
            removeKey(value,jsonCus,key);
        });
        return cusObject;
    }


    public JSONObject removeEmptyString(String... keys) throws IOException {
        String standardJson = readJson(EMPTYSTRING);  //标准JSON
        JSONObject standMap = JSONObject.parseObject(standardJson);
        standMap.forEach((key,value)->{
            Object data = null;
            if(key.equals("data")){
                data = standMap.get("data");
            }else{
                data = ((JSONObject)standMap.get("data")).get(key);
            }
            if(data instanceof JSONArray){
                JSONArray jsonArr = (JSONArray)data; //批量保存只支持取第一条数据进行比较
                List<String> removeList = new ArrayList<>();
                for (Object jsonCuso :jsonArr){
                    Map<String,Object> j = (Map<String,Object>)jsonCuso;
                    j.forEach((jk,jv)->{
                        if(StringUtils.isEmpty(jv.toString())){
                            removeList.add(jk);
                        }
                    });
                    for (String remove:removeList){
                        j.remove(remove);
                    }
                }
            }else{
                Map<String,Object> jsonCus = (Map<String,Object>)data;
                List<String> removeList = new ArrayList<>();
                jsonCus.forEach((jk,jv)->{
                    if(jv==null||StringUtils.isEmpty(jv.toString())||jv.toString().equals("0")||jv.toString().equals("0.0")){
                        removeList.add(jk);
                    }
                });
                for (String remove:removeList){
                    jsonCus.remove(remove);
                }
            }
        });
        return standMap;
    }


    public Map<String,Set<String>> verify(String... keys) throws IOException {
        String standardJson = readJson(STANDARDJSON);  //标准JSON
        JSONObject jsonObject = JSONObject.parseObject(standardJson);
        Map<String,Set<String>> standMap = getSets(jsonObject,keys); //获取到标准JSON的所有key
        String cusCompare = readJson(CUSCOMPARE);  //客户JSON
        JSONObject cusObject = JSONObject.parseObject(cusCompare);
        Map<String,Set<String>> cusMap = getSets(cusObject,keys); //获取到客户JSON的所有key
        //开始进行比较
        Map<String,Set<String>> result = new HashMap<>();
        standMap.forEach((mapKey,standValue)->{
            Set<String> cusValue = cusMap.get(mapKey);
            standValue.removeAll(cusValue);
            result.put(mapKey,standValue);
        });
        return result;
    }

    /**
     * 获取JSON中所有的key
     * @param jsonObject
     * @param keys
     * @return
     * @throws IOException
     */
    private Map<String,Set<String>> getSets(JSONObject jsonObject, String... keys) throws IOException {
        Map<String,Set<String>> baseMap = new HashMap<>();
        if(jsonObject.get("data") instanceof JSONArray){
            jsonObject = (JSONObject) ((JSONArray)jsonObject.get("data")).get(0); //批量保存只支持取第一条数据进行比较
        }else{
            //适配特殊场景，不存在data的场景
            JSONObject jsonObjectData = (JSONObject)jsonObject.get("data");
            jsonObject = null==jsonObjectData?jsonObject:jsonObjectData;
        }
        //去除字符串为空的字段
        Set<String> sets = new HashSet<>();
        Map<String,Object> mapToSet = (Map<String,Object>)jsonObject;
        mapToSet.forEach((key,value)->{
            if(value instanceof String && StringUtils.isEmpty(String.valueOf(value))){
                //不做处理
            }else {
                sets.add(key);
            }
        });
        baseMap.put("data",sets);//第一级数据
        if(keys.length>0){
            for(String s:keys){
                Set<String> chSets = new HashSet<>();
                //子表也是取第一条数据
                Map<String,Object> chJson = jsonObject.get(s) instanceof JSONArray?((Map<String,Object>)((JSONArray)jsonObject.get(s)).get(0)):((Map<String,Object>)jsonObject.get(s));
                chJson.forEach((key,value)->{
                    if(value instanceof String && StringUtils.isEmpty(String.valueOf(value))){
                        //不做处理
                    }else {
                        chSets.add(key);
                    }
                });
                baseMap.put(s,chSets); ////下级数据

            }
        }
        return baseMap;
    }

    private String readJson(String basePath) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource(basePath);
        BufferedReader in = new BufferedReader(new FileReader(classPathResource.getFile()));
        StringBuilder sb = new StringBuilder();
        while (in.ready()) {
            sb.append(in.readLine());
        }
        in.close();
        return  sb.toString();
    }

    /**
     * 对特殊符号！号的处理
     */
    private void doExclamationPoint(Map<String,Object> map,Set<String> params){
        params.forEach(v->{
            if(v.contains("!")){
                String[] keyArr = v.split("!"); //根据!号切分的数组
                Map<String,Object> mapCh = (Map<String,Object>)map.get(keyArr[0]); //取到对应的子表
                if(mapCh!=null&&mapCh.size()>0)map.put(v,mapCh.get(keyArr[1]));
            }
        });
    }

    /**
     * 处理移除字段数据的逻辑
     */
    private void removeKey(Set<String> value,Map<String,Object> jsonCus,String key){
        List<String> removeList = new ArrayList<>();
        if(jsonCus==null)return;
        jsonCus.forEach((jk,jv)->{
            if(!value.contains(jk)){
                String jkcode = jk+"_code";  //判断可能存在编码和id互转的情况，
                if(!value.contains(jkcode)){
                    removeList.add(jk);
                }
            }
        });
        for (String remove:removeList){
            jsonCus.remove(remove);
        }
        if(!key.equals("name"))jsonCus.put("_status","Insert");
    }


    /**
     * 处理移除子表的逻辑
     */
    private void removeChTable(String[] value,Map<String,Object> jsonCus){
        if(jsonCus==null)return;
        List<String> removeList = new ArrayList<>();
        List<String> valueList = Arrays.asList(value);
        jsonCus.forEach((jk,jv)->{
            if(!valueList.contains(jk)){
                if(jv instanceof JSONObject || jv instanceof JSONArray) removeList.add(jk);
            }
        });
        for (String remove:removeList){
            jsonCus.remove(remove);
        }
    }
}